﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using Lucene.Net.Store;
using TI;
using System.IO;
using Helper.FullTextIndex;

namespace TI_Index
{
    public class ConveyorItem
    {
        public string DocID {get;set;}

        public int Part { get; set; }

        string fileName { get; set; }
        public string FileName
        {
            get { return fileName; }
            
            set{
                    fileName = value;
                    FileInfo fi = new FileInfo(value);
                    string s = fi.Name.Replace(fi.Extension, ""); 
                    //if(s.IndexOf ("_")>-1)
                    DocID = s;}
        }


        //файл существует в индексе 0-нет в индексе,1-в индексе, -1-невозмжно добавить в индекс
        public int IndexStatus { get; set; }

        public List<string> Tags { get; set; }

        public void AddTag(string tag)
        {
            if (Tags == null)
                Tags = new List<string>();
            
            Tags.Add(tag);
        }

        public TagInfo ToTagInfo() {
            if (this.Tags == null)
                return null;
            TagInfo r = new TagInfo();
            r.Tags = this.Tags;
            return r;
        }

        //обновить информацию о тэгах в DocumentMeta 
        public void UpdateDocumentMeta() {
            if (Tags == null)
                        return;

            Helper.MongoTools t = new Helper.MongoTools();
            DocumentMetaItem itm = (DocumentMetaItem)t.GetEntity<DocumentMetaItem>("db.DocumentMeta.findOne({DocID:'" + DocID + "'});");
            
            // в папке файл от несуществующего документа
            if (itm == null)
                        return;

            itm.IsIndexed = true;
            itm.IsDownload = true;
            itm.TagInfo = this.ToTagInfo();
            Helper.MongoTools.Instance.ExecuteScript("updateDocumentMetaItem(" + itm.ToString() + ")");
        
        }
    }

    /// <summary>
    /// Абстракция над обрабатываемыми файлами.
    /// 
    /// </summary>
    public class ConveyorItems : ICollection
    {
        string worckFolder = string.Empty;
        string indexFolder = string.Empty;

        Hashtable items = new Hashtable();
        Helper.FullTextIndex.HDSearchEngine index = null; 

        public ConveyorItems(string worckFolder,string indexFolder )
        {
            this.worckFolder = worckFolder;
            this.indexFolder =indexFolder;

            index = new Helper.FullTextIndex.HDSearchEngine(this.indexFolder);
            index.OnAddFileToIndex += new Helper.FullTextIndex.HDSearchEngine.AddFileToIndex(Index_OnAddFileToIndex);

            Init();
        }

        public void LinkTag(string tag, List<SearchResult> searchResult)
        {
            foreach (SearchResult i in searchResult)
            {
                if (this.items[i.ID] != null)
                    ((ConveyorItem)this.items[i.ID]).AddTag(tag);
            }
        }

        //на основании данных индекса и файлов в папке формирует this.items
        private void Init() {
            string[] source = GetOfficeFiles();
            Console.WriteLine("Инициализация индекса");

            string id = string.Empty;
            

            foreach (string i in source)
            {
                id = Helper.FullTextIndex.HDSearchEngine.GetIndexItemID(i);
                bool f = index.CheckExist(id);
                ConveyorItem itm = new ConveyorItem() { FileName = i, IndexStatus =(f?1:0)  };
                try
                {
                    this.items.Add(id, itm);
                }
                catch
                {
                    continue;
                }
                
            }
            Console.WriteLine("Инициализация индекса OK");
        }

        /// <summary>
        /// Венуть список неиндексированных файлов. (only ofiice files)
        /// </summary>
        private string[] GetOfficeFiles()
        {
            List<string> result = new List<string>();
            string[] source = System.IO.Directory.GetFiles(worckFolder);
            foreach (string i in source)
            {
                if (AttachController.IsOfficeFile(i))
                    result.Add(i);
            }
            return result.ToArray();

        }

        /// <summary>
        /// Добавляет файлы рабочей папки в индекс
        /// </summary>
        public void MergeIndex()
        {
            List<string> source= new List<string> ();
            foreach (ConveyorItem i in this.items.Values)
            {
                if (i.IndexStatus == 0)
                    source.Add(i.FileName);
            }
            try
            {
                index.AddToIndex(source.ToArray());
            }
            catch (Helper.FullTextIndex.HDSearchEngine.AddToIndexException e)
            {
                FileInfo fi = null; 
                string newName=string.Empty;
                
                //файлы вызвавшие исключение при помещении в индекс -переименовываются
                foreach (string i in e.ErrList)
                {
                    fi = new FileInfo(i);
                    newName =i.Replace (fi.Extension,".ERR");
                    Helper.FileTools.RenameFile(i, newName); 

                }
            }
        }

        private void Index_OnAddFileToIndex(string fileName)
        {
            Console.WriteLine(fileName +" add index OK");
        }
 
        #region ICollection Members

        public void CopyTo(Array array, int index)
        {
            throw new NotImplementedException();
        }

        public int Count
        {
            get { return items.Count; }
        }

        public bool IsSynchronized
        {
            get { throw new NotImplementedException(); }
        }

        public object SyncRoot
        {
            get { throw new NotImplementedException(); }
        }

        #endregion

        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            return items.Values.GetEnumerator();
        }

        #endregion
    }
}
